/**
 *
 */
package com.ease.context.i18n;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;

import com.ease.aa.system.utility.impl.ResourceLoadHelper;

/**
 * 国际化资源注册器
 * <p>
 * 目前资源类型：异常、I18N
 * 
 * @author nathanleewei
 */
public class ResourceRegister {

	/** 资源类型：异常 */
	public static final String EXCEPTION = "EXCEPTION";

	/** 资源类型：I18N */
	public static final String I18N = "I18N";

	/**
	 * 注册资源文件.(用户)
	 * 
	 * @param resourceType
	 *            要注册的资源类型
	 * @param fileName
	 *            要注册的资源文件全称
	 */
	public static void registerResource(String resourceType, String fileName) {
		Locale locale = ResourceLoadHelper.getResourceLoacle(fileName);
		ResourceCache.USER_RESOURCE.registerResource(resourceType, locale, fileName);
		PropertiesCache.USER_PROPERTY.put(resourceType, locale, ResourceLoadHelper.loadResourceProperties(fileName));
	}

	/**
	 * 注销资源文件.(用户)
	 */
	public static void unRegisterResource(String resourceType) {
		ResourceCache.USER_RESOURCE.unRegisterResource(resourceType);
		PropertiesCache.USER_PROPERTY.clear(resourceType);
	}

	/**
	 * 注销资源文件.(用户)
	 */
	public static void unRegisterResource(String resourceType, String fileName) {
		Locale locale = ResourceLoadHelper.getResourceLoacle(fileName);
		ResourceCache.USER_RESOURCE.unRegisterResource(resourceType, locale, fileName);
		Properties property = PropertiesCache.USER_PROPERTY.get(resourceType, locale);
		if (property != null) {
			for (Object key : ResourceLoadHelper.loadResourceProperties(fileName).keySet()) {
				property.remove(key);
			}
		}
	}

	/**
	 * 重新加载资源文件(用户)
	 * 
	 * @param resourceType
	 *            要注册的资源类型
	 */
	public static void reloadResource(String resourceType) {
		PropertiesCache.USER_PROPERTY.clear(resourceType);
		Map<Locale, Set<String>> localResourceMap = ResourceCache.USER_RESOURCE.resource_cache.get(resourceType);
		if (localResourceMap != null) {
			for (Entry<Locale, Set<String>> entry : localResourceMap.entrySet()) {
				for (String resource : entry.getValue()) {
					PropertiesCache.USER_PROPERTY.put(resourceType, entry.getKey(), ResourceLoadHelper.loadResourceProperties(resource));
				}
			}
		}
	}

	/**
	 * 重新加载资源文件(用户)
	 * 
	 * @param resourceType
	 *            要注册的资源类型
	 * @param fileName
	 *            要注册的资源来源
	 */
	public static void reloadResource(String resourceType, String fileName) {
		registerResource(resourceType, fileName);
	}

	// 子资源注册器
	static class ResourceCache {
		/* 资源文件缓存器：<资源类型(异常、i18n),资源集> */
		Map<String, Map<Locale, Set<String>>> resource_cache = new HashMap<String, Map<Locale, Set<String>>>(2);

		// EOS系统资源
		static ResourceCache SYS_RESOURCE = new ResourceCache();

		// 用户资源
		static ResourceCache USER_RESOURCE = new ResourceCache();

		static {
			SYS_RESOURCE.registerResource(EXCEPTION, ResourceMessageUtil.EOS_DEFAULT_LOCALE, null);
			SYS_RESOURCE.registerResource(I18N, ResourceMessageUtil.EOS_DEFAULT_LOCALE, null);

			USER_RESOURCE.registerResource(EXCEPTION, ResourceMessageUtil.EOS_DEFAULT_LOCALE, null);
			USER_RESOURCE.registerResource(I18N, ResourceMessageUtil.EOS_DEFAULT_LOCALE, null);
		}

		/**
		 * 取得所有注册的资源文件
		 * 
		 * @return 所有注册的文件数组.
		 */
		String[] getResourceFileNames(String resourceType, Locale locale) {
			Map<Locale, Set<String>> localResourceMap = resource_cache.get(resourceType);
			if (localResourceMap != null) {
				Set<String> set = localResourceMap.get(locale);
				if (set != null) {
					return set.toArray(new String[0]);
				}
			}
			return new String[0];
		}

		void registerResource(String resourceType, Locale locale, String resource) {
			Map<Locale, Set<String>> localResourceMap = resource_cache.get(resourceType);
			if (localResourceMap == null) {
				localResourceMap = new HashMap<Locale, Set<String>>(5);
			}
			Set<String> set = localResourceMap.get(locale);
			if (set == null) {
				set = new HashSet<String>(10);
			}
			if (resource != null) {
				set.add(resource);
			}
			localResourceMap.put(locale, set);
			resource_cache.put(resourceType, localResourceMap);
		}

		void unRegisterResource(String resourceType) {
			Map<Locale, Set<String>> localResourceMap = resource_cache.get(resourceType);
			if (localResourceMap != null) {
				localResourceMap.clear();
			}
			resource_cache.remove(resourceType);
		}

		void unRegisterResource(String resourceType, Locale locale, String resource) {
			if (resource == null) {
				return;
			}
			Map<Locale, Set<String>> localResourceMap = resource_cache.get(resourceType);
			if (localResourceMap != null) {
				Set<String> set = localResourceMap.get(locale);
				if (set != null) {
					if (resource != null) {
						set.remove(resource);
					}
				}
			}
		}
	}

	static class PropertiesCache {

		/* 资源缓存器：<资源类型(异常、i18n),<语言,资源>>> */
		private Map<String, Map<Locale, Properties>> cache = new HashMap<String, Map<Locale, Properties>>(2);

		// EOS系统资源信息
		static PropertiesCache SYS_PROPERTY = new PropertiesCache();

		// 用户资源信息
		static PropertiesCache USER_PROPERTY = new PropertiesCache();

		static {
			SYS_PROPERTY.put(EXCEPTION, ResourceMessageUtil.EOS_DEFAULT_LOCALE, null);
			SYS_PROPERTY.put(I18N, ResourceMessageUtil.EOS_DEFAULT_LOCALE, null);

			USER_PROPERTY.put(EXCEPTION, ResourceMessageUtil.EOS_DEFAULT_LOCALE, null);
			USER_PROPERTY.put(I18N, ResourceMessageUtil.EOS_DEFAULT_LOCALE, null);
		}

		/**
		 * 取得资源
		 * 
		 * @param resourceType
		 * @return
		 */
		public Map<Locale, Properties> get(String resourceType) {
			Map<Locale, Properties> localeMap = cache.get(resourceType);
			if (localeMap == null) {
				put(resourceType, ResourceMessageUtil.EOS_DEFAULT_LOCALE, null);
				localeMap = cache.get(resourceType);
			}
			return localeMap;
		}

		/**
		 * 取得资源
		 * 
		 * @param resourceType
		 * @param locale
		 * @return
		 */
		public Properties get(String resourceType, Locale locale) {
			Map<Locale, Properties> localeMap = get(resourceType);
			return localeMap.get(locale);
		}

		/**
		 * 设定资源
		 * 
		 * @param resourceType
		 * @param locale
		 * @param properties
		 * @return
		 */
		public void put(String resourceType, Locale locale, Properties properties) {
			Map<Locale, Properties> localeMap = cache.get(resourceType);
			if (localeMap == null) {
				localeMap = new HashMap<Locale, Properties>(5);
			}
			Properties prop = localeMap.get(locale);
			if (prop == null) {
				prop = new Properties();
			}
			if (properties != null) {
				prop.putAll(properties);
			}
			localeMap.put(locale, prop);
			cache.put(resourceType, localeMap);
		}

		/**
		 * Clear cache.
		 */
		void clear(String resourceType) {
			Map<Locale, Properties> map = cache.get(resourceType);
			if (map != null) {
				map.clear();
				cache.remove(resourceType);
			}
		}
	}
}
/*
 * 修改历史 $Log: ResourceRegister.java,v $ 修改历史 Revision 1.1 2012/09/26 16:17:27 liwei 修改历史 init 修改历史 修改历史 Revision 1.1
 * 2012/09/09 10:16:53 liwei 修改历史 init 修改历史 修改历史 Revision 1.1 2012/09/09 09:32:25 liwei 修改历史 init 修改历史 修改历史 Revision 1.1
 * 2012/09/07 05:52:00 liwei 修改历史 init 修改历史 修改历史 Revision 1.1 2012/05/30 09:56:33 liwei 修改历史 *** empty log message ***
 * 修改历史 修改历史 Revision 1.3 2012/03/19 17:42:30 liwei 修改历史 init 修改历史 修改历史 Revision 1.2 2012/03/13 20:24:08 liwei 修改历史 init
 * 修改历史 修改历史 Revision 1.1 2012/03/13 17:17:04 liwei 修改历史 init 修改历史 修改历史 Revision 1.2 2012/03/01 06:28:11 liwei 修改历史 init
 * 修改历史 修改历史 Revision 1.1 2012/02/28 07:13:16 liwei 修改历史 init 修改历史 修改历史 Revision 1.1 2011/06/02 09:23:24 wangfeng 修改历史
 * 迁移项目 修改历史 修改历史 Revision 1.2 2010/04/09 10:09:10 wuyh 修改历史 Update:增加空值判断 修改历史 修改历史 Revision 1.1 2010/01/26 01:35:29
 * wanglei 修改历史 Add:迁移6.1CVS到6.2CVS上 修改历史 修改历史 Revision 1.1 2009/11/18 07:11:15 wanglei 修改历史 Add:提交到CVS。 修改历史 修改历史
 * Revision 1.4 2008/08/05 07:43:10 wangcq 修改历史 BUG: 11105 修改历史 异常资源加载不完整,中文部分不能加载 修改历史 修改历史 Revision 1.3 2008/07/28
 * 03:21:32 wangcq 修改历史 JIRA：EOS-2480 修改历史 国际化资源自动搜索功 修改历史 修改历史 Revision 1.2 2008/07/23 06:12:43 wuyh 修改历史 BUG:10440
 * 修改历史 异常资源文件加载不成功 修改历史 修改历史 Revision 1.1 2008/07/04 11:55:14 build 修改历史 Added by Needle,Sxn,Sccot 修改历史 修改历史 Revision
 * 1.1 2008/05/07 09:03:31 wuyh 修改历史 JIRA：EOS-1056 ,异常处理需要统一考虑国际化等特殊问题 修改历史 修改历史 Revision 1.4 2008/05/06 05:35:20 wuyh
 * 修改历史 JIRA：EOS-1056 ,异常处理需要统一考虑国际化等特殊问题 修改历史 修改历史 Revision 1.3 2008/03/06 09:06:05 wuyh 修改历史 Update:增加null设定 修改历史 修改历史
 * Revision 1.2 2007/12/29 02:54:44 wuyh 修改历史 UnitTest:修改错误的注销方式 修改历史 修改历史 Revision 1.1 2007/12/24 09:09:08 wuyh 修改历史
 * Update:国际化资源注册移动到通用工具模块 修改历史 修改历史 Revision 1.4 2007/12/19 03:56:51 wuyh 修改历史 UnitTest:去掉无用的代码 修改历史 修改历史 Revision 1.3
 * 2007/12/18 08:15:35 wuyh 修改历史 Code Review:拆分内部类 修改历史 修改历史 Revision 1.2 2007/12/06 09:27:35 wuyh 修改历史
 * Update:修改异常资源注册方式 修改历史 修改历史 Revision 1.1 2007/11/30 05:51:06 wuyh 修改历史 Code Review:ResourceRegister移动重构 修改历史 Revision
 * 1.4 2007/11/23 05:52:49 wuyh Update;增加注销接口
 * 
 * Revision 1.3 2007/11/16 09:09:33 wuyh Update;修改包依赖
 * 
 * Revision 1.2 2007/11/15 07:20:15 wangcq Code Review：根据开发规范的重构入口类名
 * 
 * Revision 1.1 2007/11/15 06:14:16 wangcq Update：重构项目名称,将国际化资源管理升级到公共服务
 * 
 * Revision 1.1 2007/11/15 06:12:37 wangcq Update：重构项目名称,将国际化资源管理升级到公共服务
 * 
 * Revision 1.1 2007/10/22 06:32:52 wangcq Add：增加国际化资源
 * 
 * Revision 1.2 2007/09/15 07:47:09 wuyh Update:server包名重构
 * 
 * Revision 1.1 2007/09/15 05:50:44 yangbt update:包名重构
 * 
 * Revision 1.4 2007/09/12 01:37:47 wangfeng Update:去掉无用的方法
 * 
 * Revision 1.3 2007/08/29 02:45:09 wuyh Update:增加reloadResource重载方法
 * 
 * Revision 1.2 2007/08/28 09:31:36 wuyh Update:增加注释
 * 
 * Revision 1.1 2007/08/28 08:46:17 wuyh Update:国际化资源加载模式重新设计
 */